﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Linq.Expressions;
using Lilium.Web.Mvc.State;

namespace Lilium.Web.Mvc
{
    //тут должны содержаться методы для доступа к данным контекста с вьюшки. По идее практически всё, 
    // связанное с обменом данными между вьюшкой и контроллером должно быть перенесено сюда.
    public static class ViewContextExtensions
    {
        public static T GetEntity<T>(this ViewContext viewContext, Expression<Func<T, bool>> predicate, bool required)
            where T : class
        { //TODO: учитывать флаг required
            if (viewContext == null) throw new ArgumentNullException("viewContext");

            var controller = viewContext.Controller;
            var repository = controller.GetRepository<T>();
            var entity = controller.ApplyFilters(repository).Where(predicate).Single();
            return entity;
        }

        public static T GetInstance<T>(this ViewContext viewContext, bool required)
        {
            if (viewContext == null) throw new ArgumentNullException("viewContext");

            return viewContext.ViewData.GetInstance<T>(required);
        }

        public static T GetInstance<T>(this ViewContext viewContext, string name, bool required)
        {
            if (viewContext == null) throw new ArgumentNullException("viewContext");

            return viewContext.ViewData.GetInstance<T>(name, required);
        }

        public static object GetParentModel(this ViewContext viewContext)
        {
            if (viewContext == null) throw new ArgumentNullException("viewContext");

            return viewContext.ViewData.GetParentModel();
        }

        public static T GetParentModel<T>(this ViewContext viewContext)
        {
            if (viewContext == null) throw new ArgumentNullException("viewContext");

            return viewContext.ViewData.GetParentModel<T>();
        }

        public static TService GetService<TService>(this ViewContext viewContext, bool required)
        {
            if (viewContext == null) throw new ArgumentNullException("viewContext");

            return viewContext.Controller.GetService<TService>(required);
        }
        /*
        public static string GetStateParameterName(this ViewContext viewContext, IStatefulObject statefulObject, string parameterName)
        {   //TODO: можно добавить проверку валидности имени параметра.
            return statefulObject.Key + "." + parameterName;
        }
        */
        public static string GetValidationMessage(this ViewContext viewContext)
        {
            if (viewContext == null) throw new ArgumentNullException("viewContext");

            return viewContext.ViewData.GetValidationMessage();
        }
    }
}